﻿using System;
using System.ComponentModel;
using System.Runtime.Serialization;

namespace Matchingo.Common.Types.Types
{
    /// <summary>
    /// This represents a lookless card, it must be serializable as it is stored in the save games
    /// </summary>
    [DataContract(IsReference = true)]
    public class Card
    {
        #region ========== Enumerations ==========

        /// <summary>
        /// The types of sides a card can have
        /// </summary>
        public enum CardSide
        {
            Front,
            Rear
        }

        #endregion

        #region ========== Public Properties ==========

        [DataMember]
        public Guid UniqueID { get; set; }

        [DataMember]
        public Guid MatchingID { get; set; }

        [DataMember]
        public bool IsDealt { get; set; }

        [DataMember]
        public bool IsMatched { get; set; }

        private CardSide _visibleSide;
        [DataMember]
        public CardSide VisibleSide
        {
            get { return _visibleSide; }
            set
            {
                _visibleSide = value;

                if (CardFlippedEvent != null)
                    CardFlippedEvent(this, new PropertyChangedEventArgs("VisibleSide"));
            }
        }

        #endregion

        #region ========== Constructors ==========

        public Card()
        {
            MatchingID = Guid.NewGuid();
            UniqueID = Guid.NewGuid();
            VisibleSide = CardSide.Rear;
            IsMatched = false;
            IsDealt = false;
        }

        /// <summary>
        /// Create a new copy of a card using all the same values except the MatchingID
        /// </summary>
        /// <param name="c"></param>
        public Card(Card c)
        {            
            MatchingID = c.MatchingID;
            UniqueID = Guid.NewGuid();
            VisibleSide = c.VisibleSide;
            IsMatched = false;
            IsDealt = false;
        }

        #endregion

        #region ========== Public Methods ==========

        public void Flip()
        {
            switch (VisibleSide)
            {
                case CardSide.Front:
                    VisibleSide = CardSide.Rear;
                    break;
                case CardSide.Rear:
                    VisibleSide = CardSide.Front;
                    break;
                default:
                    throw new ArgumentException("Unknown CardSide, cannot flip card");
            }
        }

        public void FoundMatch(Card c)
        {
            IsMatched = true;

            if (CardMatchedEvent != null)
                CardMatchedEvent(this, new PropertyChangedEventArgs("IsMatched"));
        }

        #endregion

        #region ========== Public Events ==========

        public event PropertyChangedEventHandler CardMatchedEvent;
        public event PropertyChangedEventHandler CardFlippedEvent;

        #endregion
    }
}